package com.tencent.liteav.chat;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;


import com.bluetooth.BluetoothIOClass;
import com.itianshan.wheel.R;
import com.tencent.liteav.TXLiteAVCode;
import com.tencent.liteav.beauty.TXBeautyManager;
import com.tencent.rtmp.ui.TXCloudVideoView;
import com.tencent.trtc.TRTCCloud;
import com.tencent.trtc.TRTCCloudListener;

import org.json.JSONArray;
import org.json.JSONObject;
import org.w3c.dom.Text;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import static android.content.ContentValues.TAG;
import static com.tencent.trtc.TRTCCloudDef.*;
import static com.tencent.trtc.TRTCCloudDef.TRTCRoleAnchor;
import static com.tencent.trtc.TRTCCloudDef.TRTC_APP_SCENE_VIDEOCALL;

public class ChatRoomClass {

    public static TRTCCloud                 mTRTCCloud;                 // SDK 核心类
    private boolean                         mIsFrontCamera;             // 是否前置摄像头
    private int                             mUserCount = 0;             // 房间通话人数个数
    private String                          mRoomId;                    // 房间Id
    private String                          mUserId;                    // 用户Id
    private List<String>                    mRemoteUidList = new ArrayList<>();             // 远端用户Id列表
    private List<TXCloudVideoView>          mRemoteViewList = new ArrayList<>();            // 远端画面列表
    private TXCloudVideoView                mLocalPreviewView;                              // 本地预览
    private int                             rotation = 0;                   //视频方向
    private boolean                         isInTheRoom=false;              //是否已进入房间

    private String                          cloudType;             /* 控制类型，取值如下：
     * cloud_bluetooth_car 云小车接收控制信号， 以蓝牙控制小车；
     * cloud_usb_car 云小车接收控制信号，以USB控制小车；
     * cloud_wheel 云手柄发射控制信号
     */
    private BluetoothIOClass                bluetoothIO;                //蓝牙操作器
    boolean send_hex = true;//蓝牙模块以HEX格式发送数据  透传
    private  Context applicationContext;                            //调用本类的Active上下文
    private String sign; //获取到的签名
    private TextView mConnectionState;  //展示连接信息

    public ChatRoomClass(String roomId,String userId,boolean isFrontCamera){
        this.mRoomId = roomId;
        this.mUserId = userId;
        this.mIsFrontCamera = isFrontCamera;
    }
    public void prepareToEnterRoom(Context applicationContext,TextView mConnectionState) {
        this.applicationContext = applicationContext;
        this.mConnectionState = mConnectionState;
        mConnectionState.setText(applicationContext.getString(R.string.entering_room));
        if(GenerateGetUserSig.getSignFromUrl) {//从服务器获取签名
            getUserSigFromUrl(mUserId);
            //获取方式为异步，获取之后自动进入房间
        }else {
            sign = GenerateGetUserSig.genTestUserSig(mUserId); //直接算出签名
            enterRoom();
        }
    }
    public void enterRoom() {
        mTRTCCloud = TRTCCloud.sharedInstance(applicationContext);
        mTRTCCloud.setGSensorMode(TRTC_GSENSOR_MODE_DISABLE); //关闭重力感应
        //mTRTCCloud.setGSensorMode(TRTC_GSENSOR_MODE_UIAUTOLAYOUT); //跟随界面
        mTRTCCloud.setListener(new TRTCCloudImplListener());
        TRTCVideoEncParam videoEncodeParam = new TRTCVideoEncParam();
        videoEncodeParam.videoResolution = TRTC_VIDEO_RESOLUTION_640_360;
        videoEncodeParam.videoResolutionMode = TRTC_VIDEO_RESOLUTION_MODE_LANDSCAPE; //设置分辨率模式为横屏模式
        videoEncodeParam.videoBitrate = 600;
        videoEncodeParam.videoFps = 15;
        videoEncodeParam.enableAdjustRes=false;
        mTRTCCloud.setVideoEncoderParam(videoEncodeParam);

        // 初始化配置 SDK 参数
        TRTCParams trtcParams = new TRTCParams();
        trtcParams.sdkAppId = GenerateGetUserSig.SDKAPPID;
        trtcParams.userId = mUserId;
        trtcParams.roomId = Integer.parseInt(mRoomId);
        // userSig是进入房间的用户签名，相当于密码（这里生成的是测试签名，正确做法需要业务服务器来生成，然后下发给客户端）
        trtcParams.userSig = sign;
        trtcParams.role = TRTCRoleAnchor;



        // 进入通话
        mTRTCCloud.enterRoom(trtcParams, TRTC_APP_SCENE_VIDEOCALL);

        // 开启本地声音采集并上行
        mTRTCCloud.startLocalAudio();
        // 开启本地画面采集并上行
        mTRTCCloud.startLocalPreview(mIsFrontCamera, mLocalPreviewView);
        /**
         * 设置默认美颜效果（美颜效果：自然，美颜级别：5, 美白级别：1）
         * 美颜风格.三种美颜风格：0 ：光滑  1：自然  2：朦胧
         * 视频通话场景推荐使用“自然”美颜效果
         */
        TXBeautyManager beautyManager = mTRTCCloud.getBeautyManager();
        beautyManager.setBeautyStyle(Constant.BEAUTY_STYLE_NATURE);
        beautyManager.setBeautyLevel(5);
        beautyManager.setWhitenessLevel(1);

        TRTCVideoEncParam encParam = new TRTCVideoEncParam();
        encParam.videoResolution = TRTC_VIDEO_RESOLUTION_640_360;
        encParam.videoFps = Constant.VIDEO_FPS;
        encParam.videoBitrate = Constant.RTC_VIDEO_BITRATE;
        encParam.videoResolutionMode = TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT;
        mTRTCCloud.setVideoEncoderParam(encParam);
    }
    /**
     * 离开通话
     */
    public void exitRoom() {
        mTRTCCloud.stopLocalAudio();
        mTRTCCloud.stopLocalPreview();
        mTRTCCloud.exitRoom();
        //销毁 trtc 实例
        if (mTRTCCloud != null) {
            mTRTCCloud.setListener(null);
        }
        mTRTCCloud = null;
        TRTCCloud.destroySharedInstance();
        isInTheRoom=false;
    }



    public void setCloudType(String cloudType) {
        this.cloudType = cloudType;
    }

    public void setBluetoothIO(BluetoothIOClass bluetoothIO) {
        this.bluetoothIO = bluetoothIO;
    }

    public void setRemoteUserViews(List<TXCloudVideoView> mRemoteViewList) {
        this.mRemoteViewList = mRemoteViewList;
    }

    public void setLocalPreviewView(TXCloudVideoView mLocalPreviewView) {
        this.mLocalPreviewView = mLocalPreviewView;
    }

    //切换视频旋转方向，0=0度，1=90度，2=180度，3=270度
    public void toggleRemoteViewRotation() {
        /*
        TRTC_VIDEO_ROTATION_0 = 0
        TRTC_VIDEO_ROTATION_90 = 1
        TRTC_VIDEO_ROTATION_180 = 2
        TRTC_VIDEO_ROTATION_270 = 3
         */
        if(mRemoteUidList.isEmpty()){
            return;
        }
        String remoteUid = mRemoteUidList.get(0);

        if(rotation<3) {
            rotation+=1;
        }else{
            rotation = 0;
        }
        mTRTCCloud.setRemoteViewRotation(remoteUid, rotation);
    }

    public boolean isInTheRoom() {
        return isInTheRoom;
    }


    private class TRTCCloudImplListener extends TRTCCloudListener {
        //接收控制信号
        @Override
        public void onRecvCustomCmdMsg(String userId, int cmdID, int seq, byte[] message) {
            if(message!=null) {
                String command = new String(message)+"\r\n";
                if(cloudType.equals("cloud_bluetooth_car")) {
                    //小车端接收控制信号后通过蓝牙模块发送到小车
                    if(bluetoothIO.mBluetoothLeService.isconnect(bluetoothIO.mDeviceAddress)) {
                        bluetoothIO.setCommandTime(System.currentTimeMillis());
                        bluetoothIO.mBluetoothLeService.txxx(command, send_hex);//发送字符串数据
                    }
                }else if(cloudType.equals("cloud_usb_car")){
                    //小车端接收控制信号后通过USB模块发送到小车

                }else if(cloudType.equals("cloud_wheel")){
                    //控制端接收小车返回的消息

                }
            }
        }

        @Override
        public void onUserVideoAvailable(String userId, boolean available) {
            Log.d(TAG, "onUserVideoAvailable userId " + userId + ", mUserCount " + mUserCount + ",available " + available);
            int index = mRemoteUidList.indexOf(userId);
            if (available) {
                if (index != -1) { //如果mRemoteUidList有，就不重复添加
                    return;
                }
                mRemoteUidList.add(userId);
                refreshRemoteVideoViews();
            } else {
                if (index == -1) { //如果mRemoteUidList没有，说明已关闭画面
                    return;
                }
                /// 关闭用户userId的视频画面
                mTRTCCloud.stopRemoteView(userId);
                mRemoteUidList.remove(index);
                refreshRemoteVideoViews();
            }

        }

        private void refreshRemoteVideoViews() {
            for (int i = 0; i < mRemoteViewList.size(); i++) {
                if (i < mRemoteUidList.size()) {
                    String remoteUid = mRemoteUidList.get(i);
                    mRemoteViewList.get(i).setVisibility(View.VISIBLE);
                    // 开始显示用户userId的视频画面

                    if(cloudType.equals("cloud_wheel") && i==0) {
                        //小车传回的画面是第0个用户，显示在本地预览

                        mTRTCCloud.setRemoteViewRotation(remoteUid,TRTC_VIDEO_ROTATION_270);
                        mTRTCCloud.startRemoteView(remoteUid, mLocalPreviewView);
                    }else{
                        //mTRTCCloud.setVideoEncoderRotation(TRTC_VIDEO_ROTATION_90);
                        mTRTCCloud.startRemoteView(remoteUid, mRemoteViewList.get(i));
                    }
                } else {
                    mRemoteViewList.get(i).setVisibility(View.GONE);
                }
            }
        }


        // 错误通知监听，错误通知意味着 SDK 不能继续运行
        @Override
        public void onError(int errCode, String errMsg, Bundle extraInfo) {
            Log.d(TAG, "sdk callback onError");
            if (applicationContext != null) {
                Toast.makeText(applicationContext, "onError: " + errMsg + "[" + errCode+ "]sign:"+sign , Toast.LENGTH_SHORT).show();
                if (errCode == TXLiteAVCode.ERR_ROOM_ENTER_FAIL) {
                    exitRoom();
                }
            }
        }

        //成功进入房间
        @Override
        public void  onEnterRoom(long result){
            if(result>=0) {
                //int resId = applicationContext.getResources().getIdentifier("W".concat(String.valueOf(result)), "string", applicationContext.getPackageName());
                mConnectionState.setText(applicationContext.getString(R.string.entered_room).concat(mRoomId));
                /*

                Timer timer = new Timer();
                TimerTask task = new TimerTask() {
                    @Override
                    public void run() {
                        mConnectionState.setText("");
                    }
                };
                timer.schedule(task, 3000);

                 */
                isInTheRoom = true;
            }else{
                int resId = applicationContext.getResources().getIdentifier("E".concat(String.valueOf(Math.abs(result))), "string", applicationContext.getPackageName());

                if(resId==0) {
                    mConnectionState.setText(String.valueOf(result));
                }else {
                    mConnectionState.setText(applicationContext.getString(resId));
                }

                isInTheRoom = false;
            }
        }
    }

    //从服务器获取签名
    public void getUserSigFromUrl(String userId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String getSignUrl = GenerateGetUserSig.getSignUrl;
                getSignUrl = getSignUrl.concat(userId);
                try {
                    //你的URL
                    URL url = new URL(getSignUrl);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    //设置连接属性。不喜欢的话直接默认也阔以
                    conn.setConnectTimeout(5000);//设置超时
                    conn.setUseCaches(false);//数据不多不用缓存了
                    //这里连接了
                    conn.connect();
                    //这里才真正获取到了数据
                    int responsCode = conn.getResponseCode();
                    if (responsCode == 200) {//200意味着返回的是"OK"
                        InputStream inputStream = conn.getInputStream();
                        InputStreamReader input = new InputStreamReader(inputStream);
                        BufferedReader buffer = new BufferedReader(input);
                        mConnectionState.setText(String.valueOf(conn.getErrorStream()));

                        String inputLine;
                        StringBuffer resultData = new StringBuffer();//StringBuffer字符串拼接很快
                        while ((inputLine = buffer.readLine()) != null) {
                            resultData.append(inputLine);
                        }
                        //在子线程中将Message对象发出去
                        Message message = new Message();
                        message.what=1;
                        message.obj = resultData;
                        handler.sendMessage(message);
                        //sign_json_string = resultData.toString();
                        //Log.v("out---------------->", sign_json_string);
                    }else{
                        Message message = new Message();
                        message.what=2;
                        message.obj = applicationContext.getString(R.string.sign_server_error).concat(String.valueOf(conn.getResponseCode()));
                        handler.sendMessage(message);
                    }
                } catch (Exception e) {
                    Message message = new Message();
                    message.what=2;
                    message.obj = applicationContext.getString(R.string.enter_room_error).concat(e.getMessage());
                    handler.sendMessage(message);
                    e.printStackTrace();
                }
            }
        }).start();
    }

    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            if (msg.what == 1)
            {   try {
                    JSONObject jsonObject = new JSONObject(msg.obj.toString());
                    //getJSONArray中的参数就是你想要分析的JSON的键
                    Object jsonDatas = jsonObject.get("sign");
                    sign = jsonDatas.toString();
                    //mConnectionState.setText(msg.obj.toString());
                    enterRoom();
                } catch (Exception e) {
                    e.printStackTrace();
                    mConnectionState.setText(applicationContext.getString(R.string.json_error));
                }
            }else{
                mConnectionState.setText(msg.obj.toString());
            }
            super.handleMessage(msg);
        };
    };
}
